#pragma once
#include <iostream>
#include <string>
#include <unistd.h>
#include <pthread.h>
#include <functional>
using namespace std;

// 返回值是void, 参数是T的包装器
template<class T>
using fun = function<void(T)>;

static int NUM = 1;
template<class T>
class Thread
{
public:
    Thread(fun<T> f, T data = 0) : _f(f), _data(data)
    {}

    // 让线程执行StartRoutine函数
    void Run() 
    {
        _name = "Thread-" + to_string(NUM++);
        _isRunning = true;
        pthread_create(&_tid, nullptr, StartRoutine, this);
    }

    static void* StartRoutine(void* args) 
    {
        Thread* td = static_cast<Thread*>(args);
        td->Entry();
        return nullptr;
    }

    void Join()
    {
        pthread_join(_tid, nullptr);
        _isRunning = false;
    }

    string GetName()
    {
        return _name;
    }

    bool IsRunning() 
    {
        return _isRunning;
    }

    // 回调fun
    void Entry()
    {
        _f(_data);
    }

    pthread_t GetTid()
    {
        return _tid;
    }
private:
    pthread_t _tid = 0;
    string _name = "";
    bool _isRunning = false;
    T _data;     // 函数的参数
    fun<T> _f;      // 让线程执行某一个任务
};
